package us.feng.tinyspring.beans.factory.xml;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import us.feng.tinyspring.beans.BeanDefinition;
import us.feng.tinyspring.beans.GenericBeanDefinition;
import us.feng.tinyspring.beans.PropertyValue;
import us.feng.tinyspring.beans.factory.DefaultListableBeanFactory;
import us.feng.tinyspring.beans.factory.config.RuntimeBeanReference;
import us.feng.tinyspring.util.StringUtils;

public class BeanDefinitionParserDelegate {
	
	public static final String BEAN_ELEMENT="bean";
	public static final String ID_ATTRIBUTE="id";
	public static final String CLASS_ATTRIBUTE = "class";
	public static final String PROPERTY_ELEMENT="property";
	public static final String NAME_ATTRIBUTE="name";
	
	public static final String REF_ATTRIBUTE="ref";
	public static final String VALUE_ATTRIBUTE="value";
	
	private static final Logger LOGGER=LoggerFactory.getLogger(BeanDefinitionParserDelegate.class);

	private XmlBeanDefinitionReader reader;
	
	public BeanDefinitionParserDelegate(XmlBeanDefinitionReader reader){
		this.reader=reader;
	}

	public BeanDefinition parseBeanDefinitionElement(Element ele,String beanName) {
		GenericBeanDefinition beanDefinition=new GenericBeanDefinition();
		
		String className = null;
		if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
			className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
		}
		
		beanDefinition.setBeanClassName(className);
		// 解析属性
		parsePropertyElements(ele, beanDefinition,beanName);
	
		//beanDefinition.
		return beanDefinition;
	}

	public void parsePropertyElements(Element ele, BeanDefinition beanDefinition,String beanName) {
		NodeList nl=ele.getChildNodes();
		for(int i=0;i<nl.getLength();i++){
			Node node=nl.item(i);
			if(node instanceof Element && PROPERTY_ELEMENT.equals(node.getNodeName())){
				String propertyName=((Element) node).getAttribute(NAME_ATTRIBUTE);
				if(StringUtils.isNullOrEmpty(propertyName)){
					return;
				}
				Object value=parsePropertyValue((Element)node, beanDefinition, propertyName);
				
				LOGGER.debug("Parse property: [{}]->[{}] of Bean [{}]",propertyName,value.getClass(),beanName);
				
				beanDefinition.getPropertyValues().addPropertyValue(new PropertyValue(propertyName, value));
			}
		}
	}
	
	private Object parsePropertyValue(Element ele,BeanDefinition beanDefinition,String propertyName){
		Object object=null;
		if(ele.hasAttribute(VALUE_ATTRIBUTE)){
			// TODO: value直接获取
			object=ele.getAttribute(VALUE_ATTRIBUTE);
		}else if(ele.hasAttribute(REF_ATTRIBUTE)){
			// 生成Ref对象
			String beanName=ele.getAttribute(REF_ATTRIBUTE);
			object=new RuntimeBeanReference(beanName);
		}
		
		return object;
	}

}
